package com.dusk.encrypt
{
	
	import com.adobe.crypto.AES;
	import flash.utils.ByteArray;
	import flash.utils.getQualifiedClassName;
	
	
	public class JSONEncrypt
	{
		
		private static const TYPE_INT:String = "int";
		
		private static const TYPE_NUMBER:String = "number";
		
		private static const TYPE_STRING:String = "string";
		
		private static const TYPE_BOOLEAN:String = "boolean";
		
		private static const TYPE_NULL:String = "null";
		
		private static const TYPE_UNDEFINED:String = "undefined";
		
		private static var cipher:String = getQualifiedClassName(new ByteArray());
		
		public static function encryptObject(data:Object):Object
		{
			return JSON.parse(JSON.stringify(data, jsonReplacer));
		}
		
		public static function decryptObject(data:Object):Object
		{
			return JSON.parse(JSON.stringify(data, jsonParser));
		}
		
		/**
		 * 用于JSON的加密
		 * @param k 键名
		 * @param v 键值
		 * @return
		 */
		public static function jsonReplacer(k:*, v:*):*
		{
			if (v == null)
			{
				return encryptString(TYPE_NULL + "_null");
			}
			if (v == undefined)
			{
				return encryptString(TYPE_UNDEFINED + "_undefined");
			}
			if (v is int)
			{
				return encryptString(TYPE_INT + "_" + v.toString());
			}
			if (v is Number)
			{
				return encryptString(TYPE_NUMBER + "_" + v.toString());
			}
			if (v is String)
			{
				return encryptString(TYPE_STRING + "_" + v.toString());
			}
			if (v is Boolean)
			{
				return encryptString(TYPE_BOOLEAN + "_" + v.toString());
			}
			return v;
		}
		
		/**
		 * 用于JSON的解密
		 * @param k 键名
		 * @param v 键值
		 * @return
		 */
		public static function jsonParser(k:*, v:*):*
		{
			if (!(v is String))
			{
				return v;
			}
			v = decryptString(v.toString());
			var getType:Function = function (data:String):String
			{
				return data.split("_")[0];
			}
			var getValue:Function = function (data:String):String
			{
				return data.split("_")[1];
			}
			switch (getType(v))
			{
				case TYPE_INT:
					return parseInt(getValue(v));
				case TYPE_NUMBER:
					return parseFloat(getValue(v));
				case TYPE_STRING:
					return getValue(v);
				case TYPE_BOOLEAN:
					return getValue(v) == "true";
				case TYPE_NULL:
					return null;
				case TYPE_UNDEFINED:
					return undefined;
			}
		}
		
		private static function encryptString(value:String):String
		{
			return value;
			return AES.saltEncrypt(value,cipher,"hex");
		}
		
		private static function decryptString(value:String):String
		{
			return value;
			return AES.saltDecrypt(value,cipher,"hex");
		}
	}
}
